package com.gopay.scheduler;


import com.gopay.common.constants.scheduler.SchedulerConstants;
import com.gopay.scheduler.service.jobmonitor.impl.CronSchedulerListener;
import com.gopay.scheduler.service.jobmonitor.impl.CronTriggerListener;
import com.gopay.scheduler.shedulerx.SchedulerOperateFactory;
import org.apache.commons.lang3.StringUtils;
import org.quartz.*;
import org.quartz.impl.matchers.KeyMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.CronTriggerBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @GopaySchedulerFactory.java
 * @author fanghw 
 * @2015年10月8日 上午10:34:44  www.gopay.com.cn Inc.All rights reserved.
 */
public class GopaySchedulerFactory extends SchedulerFactoryBean implements ApplicationContextAware {
    private final static Logger logger = LoggerFactory.getLogger(GopaySchedulerFactory.class);
    
    private ApplicationContext applicationContext;

    @Resource(name = "serverTriggerMap")
    private Map<String,List<CronTriggerBean>> serverTriggerMap;

    @Resource(name = "cronJobListener")
    private CronTriggerListener cronTriggerListener;

    @Resource(name = "cronSchedulerListener")
    private CronSchedulerListener cronSchedulerListener;

    public static String switchType;
    
    private boolean switchREALTIME;
    private boolean switchFIXEDTIME;
    private boolean switchMAJOR;
    private boolean switchORTHER;

    private boolean switchPAYBANK;

    private boolean switchPAYBANKMT;

    private boolean switchASYNCEXPORT;

    private List<Trigger> cronJobList;

    //2018/05/29 byp 添加此代码 start
    /**
     * key:switchType
     * value: list
     */
    private Map<String,List<Trigger>> appMap = new HashMap<>(10);
    //2018/05/29 byp 添加此代码 end

    public void init() throws Exception {
        logger.error("------------初始化触发器列表 start-------------");
        //获取触发器列表

        List<Trigger> triggerList=new ArrayList<Trigger>();
        List<Trigger> appTriggerList=null;
        if(switchREALTIME){
            triggerList.addAll(serverTriggerMap.get("JOB_REALTIME"));
            switchType = "JOB_REALTIME";
            //2018/05/29 byp 添加此代码 start
            appTriggerList=new ArrayList<>();
            appTriggerList.addAll(serverTriggerMap.get("JOB_REALTIME"));
            appMap.put(switchType.toUpperCase(),appTriggerList);
            //2018/05/29 byp 添加此代码 end
            logger.error("--switchREALTIME="+switchREALTIME);
        }
        if(switchFIXEDTIME){
            triggerList.addAll(serverTriggerMap.get("JOB_FIXEDTIME"));
            switchType = "JOB_FIXEDTIME";
            //2018/05/29 byp 添加此代码 start
            appTriggerList=new ArrayList<>();
            appTriggerList.addAll(serverTriggerMap.get("JOB_FIXEDTIME"));
            appMap.put(switchType.toUpperCase(),appTriggerList);
            //2018/05/29 byp 添加此代码 end
            logger.error("--switchFIXEDTIME="+switchFIXEDTIME);
        }
        if(switchMAJOR){
        	triggerList.addAll(serverTriggerMap.get("JOB_MAJOR"));
        	switchType = "JOB_MAJOR";
            //2018/05/29 byp 添加此代码 start
            appTriggerList=new ArrayList<>();
            appTriggerList.addAll(serverTriggerMap.get("JOB_MAJOR"));
            appMap.put(switchType.toUpperCase(),appTriggerList);
            //2018/05/29 byp 添加此代码 end
        	logger.error("--switchMAJOR="+switchMAJOR);
        }
        if(switchORTHER){
            triggerList.addAll(serverTriggerMap.get("JOB_ORTHER"));
            switchType = "JOB_OTHER";
            //2018/05/29 byp 添加此代码 start
            appTriggerList=new ArrayList<>();
            appTriggerList.addAll(serverTriggerMap.get("JOB_ORTHER"));
            appMap.put(switchType.toUpperCase(),appTriggerList);
            //2018/05/29 byp 添加此代码 end
            logger.error("--switchORTHER="+switchORTHER);
        }

        //单笔付款到银行
        if(switchPAYBANK){
            triggerList.addAll(serverTriggerMap.get("JOB_PAYBANK"));
            switchType = "switchPAYBANK";
            //2018/05/29 byp 添加此代码 start
            appTriggerList=new ArrayList<>();
            appTriggerList.addAll(serverTriggerMap.get("JOB_PAYBANK"));
            appMap.put("JOB_PAYBANK",appTriggerList);
            //2018/05/29 byp 添加此代码 end
            logger.error("--switchPAYBANK="+switchPAYBANK);
        }

        //单笔付款到银行
        if(switchPAYBANKMT){
            triggerList.addAll(serverTriggerMap.get("JOB_PAYBANK_MT"));
            switchType = "switchPAYBANKMT";
            //2018/05/29 byp 添加此代码 start
            appTriggerList=new ArrayList<>();
            appTriggerList.addAll(serverTriggerMap.get("JOB_PAYBANK_MT"));
            appMap.put("JOB_PAYBANK_MT",appTriggerList);
            //2018/05/29 byp 添加此代码 end
            logger.error("--switchPAYBANKMT="+switchPAYBANKMT);
        }
        // 异步导出 add by sh.jiao 20170930
        if(switchASYNCEXPORT) {
            triggerList.addAll(serverTriggerMap.get("JOB_ASYNCEXPORT"));
            switchType = "switchASYNCEXPORT";
            //2018/05/29 byp 添加此代码 start
            appTriggerList=new ArrayList<>();
            appTriggerList.addAll(serverTriggerMap.get("JOB_ASYNCEXPORT"));
            appMap.put("JOB_ASYNCEXPORT",appTriggerList);
            //2018/05/29 byp 添加此代码 end
            logger.error("--switchASYNCEXPORT="+switchASYNCEXPORT);
        }
       
        
        logger.error("-------------triggerArr.length="+triggerList.size());
        
        //设置要执行的触发器
        String jobDetailName;
        List<Matcher<TriggerKey>> jobKeyList = new ArrayList<>();
        JobDetail jobDetail;
        for(Trigger trigger:triggerList){
            jobDetailName=trigger.getJobKey().getName();
            logger.error("********jobDetailName="+jobDetailName);
            jobDetail=(JobDetail)applicationContext.getBean(jobDetailName);
            this.getScheduler().scheduleJob(jobDetail, trigger);
        }
        //2018/05/29 byp 添加此代码 start
        if(schedulerX) {
            initSchedulerX(triggerList);
        }
        //2018/05/29 byp 添加此代码 end
        for(Trigger trigger:cronJobList) {
            Matcher<TriggerKey> matcher = KeyMatcher.keyEquals(trigger.getKey());
            jobKeyList.add(matcher);
        }
        this.getScheduler().getListenerManager().addTriggerListener(cronTriggerListener, jobKeyList);
        this.getScheduler().getListenerManager().addSchedulerListener(cronSchedulerListener);

        //启动定时任务
        this.getScheduler().start();
        
        
        logger.error("------------定时任务启动成功-------------");
        logger.info("共有 " + triggerList.size() + " 个任务 任务明细 triggerList=" + triggerList);
        logger.error("------------初始化触发器列表 end-------------");
    }


    public void setSwitchREALTIME(boolean switchREALTIME) {
		this.switchREALTIME = switchREALTIME;
	}

	public void setSwitchFIXEDTIME(boolean switchFIXEDTIME) {
		this.switchFIXEDTIME = switchFIXEDTIME;
	}

	public void setSwitchMAJOR(boolean switchMAJOR) {
		this.switchMAJOR = switchMAJOR;
	}

	public void setSwitchORTHER(boolean switchORTHER) {
		this.switchORTHER = switchORTHER;
	}

    public void setSwitchPAYBANK(boolean switchPAYBANK) {
        this.switchPAYBANK = switchPAYBANK;
    }

    public void setSwitchPAYBANKMT(boolean switchPAYBANKMT) {
        this.switchPAYBANKMT = switchPAYBANKMT;
    }

    public void setSwitchASYNCEXPORT(boolean switchASYNCEXPORT) {
        this.switchASYNCEXPORT = switchASYNCEXPORT;
    }

    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    public void setCronJobList(List<Trigger> cronJobList) {
        this.cronJobList = cronJobList;
    }

    public List<Trigger> getCronJobList() {
        return cronJobList;
    }

    //2018/05/29 byp 添加此代码 start
    @Value("#{webProperties['cron.env']}")
    private String schedulerEnv;
    @Value("#{webProperties['cron.gotest']}")
    private String schedulerGotest;
    @Value("#{webProperties['cron.schedulerX']}")
    private boolean schedulerX;


    /**
     * init the schedulerX
     * @param triggerList
     * @throws SchedulerException
     * @throws SQLException
     */
    private void initSchedulerX(List<Trigger> triggerList) throws Exception {
        SchedulerOperateFactory.getFactory().builder().
                schedulerControl(this.getScheduler()).
                triggers(triggerList).
                appName(SchedulerConstants.PROJECT_NAME_CRON.toUpperCase()).
                springEnv(this.applicationContext).
                runEnv(StringUtils.isNotBlank(schedulerGotest) ? schedulerGotest.toUpperCase() : schedulerEnv.toUpperCase()).
                appMap(appMap).
                ending().
                initJob();

    }
    //2018/05/29 byp 添加此代码 end



}
